/*
 * File:                ControllerTests.cs
 * Authors:             
 * Company:             Sandia National Laboratories
 * Project:             MVC
 *
 * Copyright 2008, Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
 * or on behalf of the U.S. Government. Export of this program may require a
 * license from the United States Government. See CopyrightHistory.txt for
 * complete details.
 *
 * Reviewers:
 * Review Date:
 * Review Comments:
 *
 * Revision History:
 *
 * $Log: ControllerTests.cs,v $
 * Revision 1.4  2008/10/24 19:34:28  bstitus
 * Converted the dictionary data types to Lists and updated the code because of the different methods for List.  Bug # 1256
 *
 * Revision 1.3  2008/10/16 14:18:16  bstitus
 * Broke up the single test in to several, smaller tests based on the comments.  All tests are passing.  Bug #1263
 *
 * Revision 1.2  2008/10/14 19:35:08  bstitus
 * Added the file header that JT sent me in resolution of bug #1252.
 *
 *
 */

using NUnit.Framework;
using Sandia.MVCFramework.Common;
using Sandia.MVCFramework.Controller;
using Sandia.MVCFramework.DataAccessor;
using Sandia.MVCFramework.DataAnalyzer;
using Sandia.MVCFramework.DataStore;
using Sandia.MVCFramework.Request;
using Sandia.MVCFramework.ViewManager;
using Sandia.MVCFramework.Test;
using Sandia.MVCFramework.TestPlugin.DataAccessor;
using Sandia.MVCFramework.TestPlugin.DataAnalyzer;
using Sandia.MVCFramework.TestPlugin.DataStore;
using Sandia.MVCFramework.TestPlugin.Request;
using Sandia.MVCFramework.TestPlugin.ViewManager;
using System;
using System.Collections.Generic;
using System.Text;

namespace Sandia.MVCFramework.Test
{
    [TestFixture]
    public class ControllerTests : FailOnErrorLoggingTestFixture
    {
        DummyStandardController controller;

        DummyRequestProcessor requestProcessor1;
        DummyRequestProcessor requestProcessor2;

        DummyDataAccessor dataAccessor1;
        DummyDataAccessor dataAccessor2;

        DummyDataAnalyzer dataAnalyzer1;
        DummyDataAnalyzer dataAnalyzer2;

        DummyDataStore dataStore1;
        DummyDataStore dataStore2;
        DummyViewManager viewManager1;
        DummyViewManager viewManager2;

        /// <summary>
        /// Set-up for the controller tests
        /// </summary>
        [TestFixtureSetUp] //run once for all of these tests
        public void ControllerTestsSetUp()
        {
            // DummyStandardController just adds some accessor methods to 
            // StandardController for testing purposes.
            controller = new DummyStandardController();

            requestProcessor1 = new DummyRequestProcessor();
            requestProcessor2 = new DummyRequestProcessor();

            dataAccessor1 = new DummyDataAccessor();
            dataAccessor2 = new DummyDataAccessor();

            dataAnalyzer1 = new DummyDataAnalyzer();
            dataAnalyzer2 = new DummyDataAnalyzer();

            dataStore1 = new DummyDataStore(null, null);
            dataStore2 = new DummyDataStore(null, null);

            viewManager1 = new DummyViewManager(null, null);
            viewManager2 = new DummyViewManager(null, null);
        }

        /// <summary>
        /// Test the AddRequestRouting method
        /// </summary>
        [Test]
        public void Test01AddRequestRouting()
        {
            // Test AddRequestRouting

            controller.AddRequestRouting(typeof(ARequest), requestProcessor1);
            controller.AddRequestRouting(typeof(BRequest), requestProcessor2);

            Assert.IsTrue(
                controller.RequestRoutings.ContainsKey(typeof(ARequest)),
                "Request routing not added correctly.");

            Assert.IsTrue(
                controller.RequestRoutings[typeof(ARequest)].Contains(requestProcessor1),
                "RequestProcessor not added correctly.");

            Assert.IsTrue(
                controller.RequestRoutings.ContainsKey(typeof(BRequest)),
                "Request routing not added correctly.");

            Assert.IsTrue(
                controller.RequestRoutings[typeof(BRequest)].Contains(requestProcessor2),
                "RequestProcessor not added correctly.");
        }

        /// <summary>
        /// Test the RouteRequestSynchronously method
        /// </summary>
        [Test]
        public void Test02RouteRequestSynchronously()
        {
            // Test RouteRequestSynchronously

            ARequest aRequest1 = new ARequest();

            controller.RouteRequestSynchronously(aRequest1);

            Assert.AreEqual(
                aRequest1,
                requestProcessor1.LastProcessedRequest,
                "Request not routed correctly.");

            Assert.AreEqual(
                null,
                requestProcessor2.LastProcessedRequest,
                "Request not routed correctly.");

            BRequest bRequest1 = new BRequest();

            controller.RouteRequestSynchronously(bRequest1);

            Assert.AreEqual(
                aRequest1,
                requestProcessor1.LastProcessedRequest,
                "Request not routed correctly.");

            Assert.AreEqual(
                bRequest1,
                requestProcessor2.LastProcessedRequest,
                "Request not routed correctly.");
        }

        /// <summary>
        /// Test the AddDataAccessor method
        /// </summary>
        [Test]
        public void Test03AddDataAccessor()
        {
            // Test AddDataAccessor

            controller.AddDataAccessor(dataAccessor1);
            controller.AddDataAccessor(dataAccessor2);

            Assert.AreEqual(
                controller.DataAccessors.Count,
                2,
                "Incorrect number of DataAccessors were added.");

            Assert.IsTrue(
                controller.DataAccessors.Contains(dataAccessor1),
                "DataAccessor was not added correctly.");

            Assert.IsTrue(
                controller.DataAccessors.Contains(dataAccessor2),
                "DataAccessor was not added correctly.");
        }

        /// <summary>
        /// Test the AddDataAnalyzer method
        /// </summary>
        [Test]
        public void Test04AddDataAnalyzer()
        {
            // Test AddDataAnalyzer

            controller.AddDataAnalyzer(dataAnalyzer1);
            controller.AddDataAnalyzer(dataAnalyzer2);

            Assert.AreEqual(
                controller.DataAnalyzers.Count,
                2,
                "Incorrect number of DataAnalyzers were added.");
            Assert.IsTrue(
                controller.DataAnalyzers.Contains(dataAnalyzer1),
                "DataAnalyzer was not added correctly.");
            Assert.IsTrue(
                controller.DataAnalyzers.Contains(dataAnalyzer2),
                "DataAnalyzer was not added correctly.");
        }

        /// <summary>
        /// Test the AddDataStore method
        /// </summary>
        [Test]
        public void Test05AddDataStore()
        {
            // Test AddDataStore

            controller.AddDataStore(dataStore1);
            controller.AddDataStore(dataStore2);

            Assert.AreEqual(
                controller.DataStores.Count,
                2,
                "Incorrect number of DataStores were added.");

            Assert.IsTrue(
                controller.DataStores.Contains(dataStore1),
                "DataStore was not added correctly.");

            Assert.IsTrue(
                controller.DataStores.Contains(dataStore2),
                "DataStore was not added correctly.");
        }

        /// <summary>
        /// Test the AddViewManager method
        /// </summary>
        [Test]
        public void Test06AddViewManager()
        {
            // Test AddViewManager

            controller.AddViewManager(viewManager1);
            controller.AddViewManager(viewManager2);

            Assert.AreEqual(
                controller.ViewManagers.Count,
                2,
                "Incorrect number of ViewManagers were added.");

            Assert.IsTrue(
                controller.ViewManagers.Contains(viewManager1),
                "ViewManager was not added correctly.");

            Assert.IsTrue(
                controller.ViewManagers.Contains(viewManager2),
                "ViewManager was not added correctly.");
        }

        /// <summary>
        /// Test the start method
        /// </summary>
        [Test]
        public void Test07Start()
        {
            // Test Start
            controller.Start();

            Assert.IsTrue(dataAccessor1.Started, "DataAccessor was not started.");
            Assert.IsTrue(dataAccessor2.Started, "DataAccessor was not started.");

            Assert.IsTrue(dataAnalyzer1.Started, "DataAnalyzer was not started.");
            Assert.IsTrue(dataAnalyzer2.Started, "DataAnalyzer was not started.");

            Assert.IsTrue(dataStore1.Started, "DataStore was not started.");
            Assert.IsTrue(dataStore2.Started, "DataStore was not started.");

            Assert.IsTrue(viewManager1.Started, "ViewManager was not started.");
            Assert.IsTrue(viewManager2.Started, "ViewManager was not started.");
        }

        /// <summary>
        /// Test the RemoveDataAccessor method
        /// </summary>
        [Test]
        public void Test08RemoveDataAccessor()
        {
            // Test RemoveDataAccessor

            controller.RemoveDataAccessor(dataAccessor1);

            Assert.AreEqual(
                controller.DataAccessors.Count,
                1,
                "DataAccessor not removed correctly.");

            Assert.IsFalse(
                controller.DataAccessors.Contains(dataAccessor1),
                "DataAccessor not removed correctly.");

            Assert.IsTrue(
                controller.DataAccessors.Contains(dataAccessor2),
                "DataAccessor not removed correctly.");
        }

        /// <summary>
        /// Test the RemoveDataAnalyzer method
        /// </summary>
        [Test]
        public void Test09RemoveDataAnalyzer()
        {
            // Test RemoveDataAnalyzer

            controller.RemoveDataAnalyzer(dataAnalyzer1);

            Assert.AreEqual(
                controller.DataAnalyzers.Count,
                1,
                "DataAnalyzer not removed correctly.");

            Assert.IsFalse(
                controller.DataAnalyzers.Contains(dataAnalyzer1),
                "DataAnalyzer not removed correctly.");

            Assert.IsTrue(
                controller.DataAnalyzers.Contains(dataAnalyzer2),
                "DataAnalyzer not removed correctly.");
        }

        /// <summary>
        /// Test the RemoveDataStore method
        /// </summary>
        [Test]
        public void Test10RemoveDataStore()
        {
            // Test RemoveDataStore

            controller.RemoveDataStore(dataStore1);

            Assert.AreEqual(
                controller.DataStores.Count,
                1,
                "DataStore not removed correctly.");

            Assert.IsFalse(
                controller.DataStores.Contains(dataStore1),
                "DataStore not removed correctly.");

            Assert.IsTrue(
                controller.DataStores.Contains(dataStore2),
                "DataStore not removed correctly.");
        }

        /// <summary>
        /// Test the RemoveViewManager method
        /// </summary>
        [Test]
        public void Test11RemoveViewManager()
        {
            // Test RemoveViewManager

            controller.RemoveViewManager(viewManager1);

            Assert.AreEqual(
                controller.ViewManagers.Count,
                1,
                "ViewManager not removed correctly.");

            Assert.IsFalse(
                controller.ViewManagers.Contains(viewManager1),
                "ViewManager not removed correctly.");

            Assert.IsTrue(
                controller.ViewManagers.Contains(viewManager2),
                "ViewManager not removed correctly.");
        }

        /// <summary>
        /// Test the RemoveRequestRouting method
        /// </summary>
        [Test]
        public void Test12RemoveRequestRouting()
        {
            // Test RemoveRequestRouting

            controller.RemoveRequestRouting(typeof(ARequest), requestProcessor1);

            Assert.IsFalse(
                controller.RequestRoutings[typeof(ARequest)].Contains(requestProcessor1),
                "RequestProcessor not removed correctly.");

            Assert.IsTrue(
                controller.RequestRoutings.ContainsKey(typeof(BRequest)),
                "Request routing not removed correctly.");

            Assert.IsTrue(
                controller.RequestRoutings[typeof(BRequest)].Contains(requestProcessor2),
                "RequestProcessor not removed correctly.");
        }

        /// <summary>
        /// A dummy request processor
        /// </summary>
        public class DummyRequestProcessor : IRequestProcessor
        {
            private IRequest lastProcessedRequest = null;

            public IRequest LastProcessedRequest
            {
                get
                {
                    return this.lastProcessedRequest;
                }
            }

            private bool isDisposed = false;

            #region IRequestProcessor Members

            public IList<Type> DesiredRequests
            {
                get { throw new Exception("The method or operation is not implemented."); }
            }

            public void ProcessRequest(IRequest request)
            {
                this.lastProcessedRequest = request;
            }

            public bool IsDisposed
            {
                get { return this.isDisposed; }
            }

            public event EventHandler Disposed;

            #endregion

            #region IDisposable Members

            public void Dispose()
            {
                this.isDisposed = true;
                if (this.Disposed != null)
                {
                    this.Disposed(this, new EventArgs());
                }
            }

            #endregion
        }

        /// <summary>
        /// A dummy standard controller
        /// </summary>
        public class DummyStandardController : StandardController
        {
            public Dictionary<Type, List<IRequestProcessor>> RequestRoutings
            {
                get
                {
                    return this.requestRoutings;
                }
            }

            public List<IDataAccessor> DataAccessors
            {
                get
                {
                    return this.dataAccessors;
                }
            }

            public List<IDataAnalyzer> DataAnalyzers
            {
                get
                {
                    return this.dataAnalyzers;
                }
            }

            public List<IDataStore> DataStores
            {
                get
                {
                    return this.dataStores;
                }
            }

            public List<IViewManager> ViewManagers
            {
                get
                {
                    return this.viewManagers;
                }
            }
        }
    }
}
